﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Sunny.Lib.DllHelper
{
    public class User32
    {
        #region HotKey
        //如果函数执行成功，返回值不为0。
        //如果函数执行失败，返回值为0。要得到扩展错误信息，调用GetLastError。
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(
            IntPtr hWnd,                //要定义热键的窗口的句柄
            int id,                     //定义热键ID（不能与其它ID重复）           
            KeyModifiers fsModifiers,   //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
            Keys vk                     //定义热键的内容
            );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(
            IntPtr hWnd,                //要取消热键的窗口的句柄
            int id                      //要取消热键的ID
            );

        //定义了辅助键的名称（将数字转变为字符以便于记忆，也可去除此枚举而直接使用数值）
        [Flags()]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            WindowsKey = 8
        }

        /*在FormA的Activate事件中注册热键，本例中注册Shift+S，Ctrl+Z，Alt+D这三个热键。这里的Id号可任意设置，但要保证不被重复。
        private void Form_Activated(object sender, EventArgs e)
        {
            //注册热键Shift+S，Id号为100。HotKey.KeyModifiers.Shift也可以直接使用数字4来表示。
            HotKey.RegisterHotKey(Handle, 100, HotKey.KeyModifiers.Shift, Keys.S); 
            //注册热键Ctrl+B，Id号为101。HotKey.KeyModifiers.Ctrl也可以直接使用数字2来表示。
            HotKey.RegisterHotKey(Handle, 101, HotKey.KeyModifiers.Ctrl, Keys.B);
            //注册热键Alt+D，Id号为102。HotKey.KeyModifiers.Alt也可以直接使用数字1来表示。
            HotKey.RegisterHotKey(Handle, 102, HotKey.KeyModifiers.Alt, Keys.D);
        }

        //在FormA的Leave事件中注销热键。
        private void FrmSale_Leave(object sender, EventArgs e)
        {
            //注销Id号为100的热键设定
            HotKey.UnregisterHotKey(Handle, 100);
            //注销Id号为101的热键设定
            HotKey.UnregisterHotKey(Handle, 101);// http://ike.126.com
            //注销Id号为102的热键设定
            HotKey.UnregisterHotKey(Handle, 102);
        }

        //重载FromA中的WndProc函数
        /// 
        /// 监视Windows消息
        /// 重载WndProc方法，用于实现热键响应
        /// 
        /// 
        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;
            //按快捷键 
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 100:    //按下的是Shift+S
                            //此处填写快捷键响应代码         
                            break;
                        case 101:    //按下的是Ctrl+B
                            //此处填写快捷键响应代码
                            break;
                        case 102:    //按下的是Alt+D
                            //此处填写快捷键响应代码
                            break;
                    }
                break;
            }
            base.WndProc(ref m);
        }*/

        #endregion

        #region SetWindowPos
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern /*return 0 indicate failed, otherwise success*/int SetWindowPos(
        int hwnd,       // 欲定位的窗口
        int hWndInsertAfter, // 参考SetWindowPosFlags1
        int x,  // 窗口新的X坐标
        int y,  // 窗口新的Y坐标
        int cx, // 指定新的窗口宽度
        int cy, // 指定新的窗口高度 
        uint wFlags //  参考SetWindowPosFlags2
        );

        // hWndInsertAfter 
        public enum SetWindowPosFlags1 : int
        {
            HWND_BOTTOM = 1,    // 把窗口放在Z轴的最后，即所有窗口的后面
            HWND_TOP = 0,       // 将窗口放在Z轴的前面，即所有窗口的前面
            HWND_TOPMOST = -1,    // 使窗口成为“TopMost”类型的窗口，这种类型的窗口总是在其它窗口的前面，真到它被关闭
            HWND_NOTOPMOST = -2,  // 将窗口放在所有“TopMost”类型窗口的后面、其它类型窗口的前面
        }

        // wFlags
        public enum SetWindowPosFlags2 : int
        {
            SWP_NOSIZE = 0x01,      // 保持当前大小 (cx和cy会被忽略) &H1 
            SWP_NOMOVE = 0x02,      // 保持当前位置 (x和y设定将被忽略) &H2 
            SWP_NOZORDER = 0x04,    // 不改变窗口听Z轴位置（即忽略hWndInsertAfter参数）
            SWP_NOREDRAW = 0x08,    // 窗口不自动重画
            SWP_NOACTIVATE = 0x10,  // 窗口移动后不激活窗口，当然，如果窗口在移动前就是激活的则例外
            SWP_DRAWFRAME = 0x20,   // 移动窗口后重画窗口及其上的所有内容
            SWP_SHOWWINDOW = 0x40,  // 显示窗口 &H40 
            SWP_HIDEWINDOW = 0x80,    // 隐藏窗口 
        } 
        #endregion

        /// <summary>
        /// 获取窗体句柄
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName">窗体名称</param>
        /// <returns>IntPtr 句柄</returns>
        [DllImport("User32.dll")]
        public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
        [DllImport("User32.dll")]
        public static extern int IsWindow(IntPtr hWnd);
        /// <summary>
        ///  该函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号。
        ///  系统给创建前台窗口的线程分配的权限稍高于其他线程。 
        /// </summary>
        /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
        /// <returns>如果窗口设入了前台，返回值为非零；如果窗口未被设入前台，返回值为零</returns>
        [DllImport("User32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
}
